﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;

namespace MutexTest
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        /**
         * System.Threading.Mutex()     用于进程间同步
         *      new Mutex()         创建匿名 mutex(线程之间)
         *      new Mutex(true)     创建匿名 mutex(线程之间), 创建mutex的线程获得mutex
         *      new Mutex(true, Application.ProductName)                创建命名 mutex(当前用户会话), 创建mutex的线程获得 mutex    
         *      new Mutex(true, @"Global\" + Application.ProductName)   创建命名 mutex(所有会话), 创建mutex的线程获得 mutex    
         *      new Mutex(true, @"Global\" + Application.ProductName, out mutexWasCreated)   
         *              创建命名 mutex(所有会话), 创建mutex的线程获得 mutex, 如果指定命名 mutex 已经存在 mutexWasCreated = false    
         *              
         *      注意:    可以多个线程同时请求 mutex, 前一个线程释放 mutex 下一个线程自动 mutex
         *              如果前一个线程异常退出(放弃mutex), 下一个获得mutex的线程中的抛出 AbandonedMutexException
         */

        Mutex mu;

        private void btnGetMutex_Click(object sender, EventArgs e)
        {
            mu = new Mutex(true);

            (new Thread(btn2GetMutex)).Start();
            (new Thread(btn3GetMutex)).Start();

            btnGetMutex.Text = "I get mutex";
            Thread.Sleep(3000);
            mu.ReleaseMutex();  // 释放当前线程的 mutex 
        }

        private void btn2GetMutex()
        {
            mu.WaitOne();
            btnGetMutex2.Text = "I get mutex";
            Thread.Sleep(3000);
            mu.ReleaseMutex();
        }

        private void btn3GetMutex()
        {
            mu.WaitOne();
            btnGetMutex3.Text = "I get mutex";
            Thread.Sleep(3000);
            mu.ReleaseMutex();
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            bool isCreated;
            var m = new Mutex(true,@"Global\" + Application.ProductName, out isCreated);
            if (! isCreated)
            {
                MessageBox.Show("当前程序不允许多开");
                System.Environment.Exit(0);
            }
        }

    }
}
